package com.wutianyi.module.product.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.SortDirection;
import com.google.appengine.api.datastore.Text;
import com.wutianyi.module.product.ProductDao;
import com.wutianyi.module.product.dataobject.ProductDO;
import com.wutianyi.module.product.dataobject.ProductDTO;
import com.wutianyi.utils.Utils;

import static com.wutianyi.entity.DataStoreField.DS_P_CID;
import static com.wutianyi.entity.DataStoreField.DS_P_VALUE;
import static com.wutianyi.entity.DataStoreField.DS_P_GDATE;
import static com.wutianyi.entity.EntityTypeEnum.Product;

public class ProductDaoDataStoreImpl implements ProductDao {
	
	private static DatastoreService datastoreService = DatastoreServiceFactory
			.getDatastoreService();
	
	private void setEntity(ProductDO product) {
		int id = 0 != product.getId() ? product.getId() : product.hashCode();
		
		product.setGmtModified(new Date());
		Entity entity = new Entity(Product.name(), id);
		entity.setProperty(DS_P_VALUE, new Text(Utils.serialize(product)));
		entity.setProperty(DS_P_CID, product.getCompanyId());
		entity.setProperty(DS_P_GDATE, product.getGmtModified());
		datastoreService.put(entity);
		product.setId(id);
	}
	
	@Override
	public ProductDTO getProductDTO() {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public int createProduct(ProductDO product) {
		product.setId(0);
		setEntity(product);
		return 1;
	}
	
	@Override
	public ProductDO getProduct(int cId, int id) {
		Query query = new Query(Product.name(), KeyFactory.createKey(Product.name(), id));
		if(0 != cId) {
			query.addFilter(DS_P_CID, FilterOperator.EQUAL, cId);
		}
		Entity entity = datastoreService.prepare(query).asSingleEntity();
		if (null != entity) {
			ProductDO product = (ProductDO) Utils.unSerialize(entity.getProperty(DS_P_VALUE));
			product.setId((int) entity.getKey().getId());
			return product;
		}
		return null;
	}
	
	@Override
	public List<ProductDO> listProductsByCompanyId(int companyId, int pageNo, int pageSize) {
		int count = listProductCountByCompanyId(companyId);
		
		if (0 == count) {
			return null;
		}
		int position = Utils.getPosition(count, pageNo, pageSize);
		
		Query query = new Query(Product.name());
		query.addFilter(DS_P_CID, FilterOperator.EQUAL, companyId);
		
		Iterable<Entity> iters = datastoreService.prepare(query).asIterable(
				FetchOptions.Builder.withOffset(position).limit(pageSize));
		List<ProductDO> products = new ArrayList<ProductDO>();
		
		for (Entity entity : iters) {
			ProductDO product = (ProductDO) Utils.unSerialize(entity.getProperty(DS_P_VALUE));
			product.setId((int) entity.getKey().getId());
			products.add(product);
		}
		
		return products;
	}
	
	//
	// @Override
	// public List<ProductDTO> listProductDTOsByCompanyId(int companyId, int
	// pageNo, int pageSize) {
	// // TODO Auto-generated method stub
	// return null;
	// }
	//
	// @Override
	// public List<ProductDTO> listProductDTOsByCompanyId(int companyId) {
	// // TODO Auto-generated method stub
	// return null;
	// }
	
	@Override
	public int listProductCountByCompanyId(int companyId) {
		Query query = new Query(Product.name());
		query.addFilter(DS_P_CID, FilterOperator.EQUAL, companyId);
		return datastoreService.prepare(query).countEntities(FetchOptions.Builder.withDefaults());
	}
	
	@Override
	public int updateProduct(ProductDO product) {
		
		setEntity(product);
		
		return 1;
	}
	
	@Override
	public List<ProductDO> listLastestProducts(int count) {
		Query query = new Query(Product.name());
		query.addSort(DS_P_GDATE, SortDirection.DESCENDING);
		Iterable<Entity> iters = datastoreService.prepare(query).asIterable(
				FetchOptions.Builder.withLimit(count));
		List<ProductDO> products = new ArrayList<ProductDO>();
		for (Entity entity : iters) {
			ProductDO product = (ProductDO) Utils.unSerialize(entity.getProperty(DS_P_VALUE));
			product.setId((int) entity.getKey().getId());
			products.add(product);
		}
		return products;
	}
	
}
